home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2007 December / PCWKCD1207B.iso / Blogowanie poza sfera / Flock 0.9.1.3 stable / flock-0.9.1.3.en-US.win32.exe / flock / components / flockAccountUtils.js < prev    next >
Text File  |  2007-10-12  |  31KB  |  899 lines

  1. // vim: ts=2 sw=2 expandtab cindent
  2. //
  3. // BEGIN FLOCK GPL
  4. // 
  5. // Copyright Flock Inc. 2005-2007
  6. // http://flock.com
  7. // 
  8. // This file may be used under the terms of of the
  9. // GNU General Public License Version 2 or later (the "GPL"),
  10. // http://www.gnu.org/licenses/gpl.html
  11. // 
  12. // Software distributed under the License is distributed on an "AS IS" basis,
  13. // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. // for the specific language governing rights and limitations under the
  15. // License.
  16. // 
  17. // END FLOCK GPL
  18. //
  19.  
  20. const ACCOUNTUTILS_CID        = Components.ID("{d84bce30-4ce5-11db-b0de-0800200c9a66}");
  21. const ACCOUNTUTILS_CONTRACTID = "@flock.com/account-utils;1";
  22.  
  23. const OBS = Components.classes["@mozilla.org/observer-service;1"]
  24.                       .getService(Components.interfaces.nsIObserverService);
  25.  
  26. // ===================================================
  27. // ========== BEGIN flockAccountUtils class ==========
  28. // ===================================================
  29.  
  30. const ACCOUNTUTILS_INTERFACES = [
  31.   Components.interfaces.nsISupports,
  32.   Components.interfaces.nsIObserver,
  33.   Components.interfaces.flockIAccountUtils,
  34. ];
  35.  
  36. function flockAccountUtils() {
  37.   this._logger = Components.classes['@flock.com/logger;1'].createInstance(Components.interfaces.flockILogger);
  38.   this._logger.init('flockAccountUtils');
  39.   this._logger.info('Created Account Utility Object');
  40.  
  41.   this.mSetupHasRun = false;
  42.   OBS.addObserver(this, "flock-data-ready", false);
  43.  
  44.   // mTempPasswords is an associative array of temporary passwords
  45.   this.mTempPasswords = [];
  46. }
  47.  
  48.  
  49. // BEGIN nsISupports interface
  50. flockAccountUtils.prototype.QueryInterface =
  51. function flockAccountUtils_QueryInterface(aIID)
  52. {
  53.   var interfaces = ACCOUNTUTILS_INTERFACES;
  54.   for (var i in interfaces) {
  55.     if (aIID.equals(interfaces[i])) {
  56.       return this;
  57.     }
  58.   }
  59.   throw Components.results.NS_ERROR_NO_INTERFACE;
  60. }
  61. // END nsISupports interface
  62.  
  63.  
  64. // BEGIN nsIObserver interface
  65. flockAccountUtils.prototype.observe =
  66. function flockAccountUtils_observe(aSubject, aTopic, aState)
  67. {
  68.   switch (aTopic) {
  69.     case 'flock-data-ready':
  70.       OBS.removeObserver(this, "flock-data-ready");
  71.       this.setup();
  72.       break;
  73.   }
  74. }
  75. // END nsIObserver interface
  76.  
  77.  
  78. // BEGIN flockIAccountUtils interface
  79. flockAccountUtils.prototype.activatedAccountExists =
  80. function flockAccountUtils_activatedAccountExists(aServiceURN)
  81. {
  82.   this._logger.info("{flockIAccountUtils}.activatedAccountExists('"+aServiceURN+"')");
  83.   this.setup();
  84.   var svc = this._coop.get(aServiceURN);
  85.   if (!svc) {
  86.     throw Components.results.NS_ERROR_UNEXPECTED;
  87.   }
  88.   var accounts = this._coop.Account.find({service: svc, isTransient: false});
  89.   return (accounts.length > 0);
  90. }
  91.  
  92. flockAccountUtils.prototype.clearTempPassword =
  93. function flockAccountUtils_clearTempPassword(aKey)
  94. {
  95.   this._logger.info("{flockIAccountUtils}.clearTempPassword('"+aKey+"')");
  96.   this.mTempPasswords[aKey] = undefined;
  97. }
  98.  
  99. flockAccountUtils.prototype.ensureOnlyAuthenticatedAccount =
  100. function flockAccountUtils_ensureOnlyAuthenticatedAccount(aAccountURN)
  101. {
  102.   this._logger.info("{flockIAccountUtils}.ensureOnlyAuthenticatedAccount('"+aAccountURN+"')");
  103.   this.setup();
  104.   var acctCoopObj = this._coop.get(aAccountURN);
  105.   if (acctCoopObj) {
  106.     var accounts = this._coop.Account.find({serviceId: acctCoopObj.serviceId});
  107.     for (var i = 0; i < accounts.length; i++) {
  108.       // Here I'm trying not to change the RDF unless I actually need to, in
  109.       // order to avoid RDF change notifications from being fired
  110.       // unnecessarily
  111.       if (accounts[i].id() == aAccountURN) {
  112.         if (!accounts[i].isAuthenticated) {
  113.           accounts[i].isAuthenticated = true;
  114.         }
  115.       } else {
  116.         if (accounts[i].isAuthenticated) {
  117.           accounts[i].isAuthenticated = false;
  118.         }
  119.       }
  120.     }
  121.   }
  122. }
  123.  
  124. flockAccountUtils.prototype.getAccountURNById =
  125. function flockAccountUtils_getAccountURNById(aServiceURN, aAccountID)
  126. {
  127.   this._logger.info("{flockIAccountUtils}.getAccountURNById('"+aServiceURN+"', '"+aAccountID+"')");
  128.   this.setup();
  129.   var svc = this._coop.get(aServiceURN);
  130.   if (!svc) {
  131.     throw Components.results.NS_ERROR_UNEXPECTED;
  132.   }
  133.   var accounts = this._coop.Account.find({service: svc, accountId: aAccountID});
  134.   this._logger.info(" - found "+accounts.length+" matching account (should be exactly 1)");
  135.   if (accounts.length > 0) {
  136.     this._logger.info(" - account urn = "+accounts[0].id());
  137.     return accounts[0].id();
  138.   }
  139.   return null;
  140. }
  141.  
  142. flockAccountUtils.prototype.getAccountURNByLogin =
  143. function flockAccountUtils_getAccountURNByLogin(aServiceURN, aLogin)
  144. {
  145.   this._logger.info("{flockIAccountUtils}.getAccountURNByLogin('"+aServiceURN+"', '"+aLogin+"')");
  146.   var pm = Components.classes["@mozilla.org/passwordmanager;1"]
  147.                      .getService(Components.interfaces.nsIPasswordManager);
  148.   var en = pm.enumerator;
  149.   while (en.hasMoreElements()) {
  150.     var p = en.getNext();
  151.     p.QueryInterface(Components.interfaces.nsIPassword);
  152.     if (p.user == aLogin && (p.host.indexOf(aServiceURN)==0)) {
  153.       var accountID = p.host.substring(aServiceURN.length+1);
  154.       return this.getAccountURNById(aServiceURN, accountID);
  155.     }
  156.   }
  157.   return null;
  158. }
  159.  
  160. flockAccountUtils.prototype.getAccountsForService =
  161. function flockAccountUtils_getAccountsForService(aServiceContractID)
  162. {
  163.   this._logger.info("{flockIAccountUtils}.getAccountsForService('"+aServiceContractID+"')");
  164.   this.setup();
  165.   var accountsEnum = {
  166.     arr : [],
  167.     QueryInterface : function(iid) {
  168.       if (!iid.equals(Components.interfaces.nsISupports) &&
  169.           !iid.equals(Components.interfaces.nsISimpleEnumerator))
  170.       {
  171.         throw Components.results.NS_ERROR_NO_INTERFACE;
  172.       }
  173.       return this;
  174.     },
  175.     hasMoreElements : function() {
  176.       return (this.arr.length > 0);
  177.     },
  178.     getNext : function() {
  179.       return this.arr.pop();
  180.     }
  181.   };
  182.   var accounts = this._coop.Account.find({serviceId: aServiceContractID});
  183.   var svc = Components.classes[aServiceContractID]
  184.                       .getService(Components.interfaces.flockIWebService);
  185.   for (var i = accounts.length - 1; i >= 0; i--) {
  186.     accountsEnum.arr.push(svc.getAccount(accounts[i].id()));
  187.   }
  188.   return accountsEnum;
  189. }
  190.  
  191. flockAccountUtils.prototype.getAccountsByInterface =
  192. function flockAccountUtils_getAccountsByInterface(aServiceInterface)
  193. {
  194.   var accountsEnum = {
  195.     arr : [],
  196.     QueryInterface : function(iid) {
  197.       if (!iid.equals(Components.interfaces.nsISupports) &&
  198.           !iid.equals(Components.interfaces.nsISimpleEnumerator))
  199.       {
  200.         throw Components.results.NS_ERROR_NO_INTERFACE;
  201.       }
  202.       return this;
  203.     },
  204.     hasMoreElements : function() {
  205.       return (this.arr.length > 0);
  206.     },
  207.     getNext : function() {
  208.       return this.arr.pop();
  209.     }
  210.   };
  211.  
  212.   var acctRoot = this._coop.get("http://flock.com/rdf#AccountsRoot");
  213.   var c_accounts = acctRoot.children.enumerate();
  214.   while (c_accounts.hasMoreElements()) {
  215.     var c_account = c_accounts.getNext();
  216.     if (Components.classes[c_account.serviceId]) {
  217.       var svc = Components.classes[c_account.serviceId]
  218.                           .getService(Components.interfaces.flockIWebService);
  219.       if (svc instanceof Components.interfaces[aServiceInterface]) {
  220.         accountsEnum.arr.push(svc.getAccount(c_account.id()));
  221.       }
  222.     } else {
  223.       this._logger.debug( "No service found for account '"+c_account.name +
  224.                           "' with serviceId: "+c_account.serviceId );
  225.     }
  226.   }
  227.  
  228.   return accountsEnum;
  229. }
  230.  
  231. flockAccountUtils.prototype.doAccountsExist =
  232. function flockAccountUtils_doAccountsExist()
  233. {
  234.   var accounts = this.getAllAccounts();
  235.   if (accounts.hasMoreElements()) {
  236.     return true;
  237.   } else {
  238.     return false;
  239.   }
  240. }
  241.  
  242. flockAccountUtils.prototype.isTransient =
  243. function flockAccountUtils_isTransient(aURN)
  244. {
  245.   return this._coop.get(aURN).isTransient;
  246. }
  247.  
  248. flockAccountUtils.prototype.getElementByAttribute =
  249. function flockAccountUtils_getElementByAttribute(aAncestorElement, aAttributeName, aAttributeValue)
  250. {
  251.   //this._logger.info("{flockIAccountUtils}.getElementByAttribute("+aAncestorElement+", '"+aAttributeName+"', '"+aAttributeValue+"')");
  252.   for (var i = 0; i < aAncestorElement.childNodes.length; i++) {
  253.     var childNode = aAncestorElement.childNodes.item(i);
  254.     try {
  255.       var childElem = childNode.QueryInterface(Components.interfaces.nsIDOMHTMLElement);
  256.       if (childElem.getAttribute(aAttributeName) == aAttributeValue) {
  257.         return childElem;
  258.       }
  259.       var recursiveResult = this.getElementByAttribute(childElem, aAttributeName, aAttributeValue);
  260.       if (recursiveResult) {
  261.         return recursiveResult;
  262.       }
  263.     } catch (ex) {
  264.       // This just means that childNode is not an Element
  265.     }
  266.   }
  267.   return null;
  268. }
  269.  
  270. flockAccountUtils.prototype.getMessageFromTransferable =
  271. function flockAccountUtils_getMessageFromTransferable(aSubject)
  272. {
  273.   this.setup();
  274.   var message = {};
  275.   message.QueryInterface = function (iid) {
  276.     if (iid.equals(Components.interfaces.flockIMessage) ||
  277.         iid.quals(Components.interfaces.nsISupports)) 
  278.     {
  279.        return this;
  280.     }
  281.     throw Components.results.NS_ERROR_NO_INTERFACE;
  282.   };
  283.   
  284.   var contentObject;
  285.   var dataObj = {}, len = {};
  286.   var flavourEnum = aSubject.flavorsTransferableCanExport().Enumerate();
  287.   try {
  288.     while (1) {
  289.       var child = flavourEnum.currentItem();
  290.       child.QueryInterface(Components.interfaces.nsISupportsCString);
  291.       if (child.data == "moz/rdfitem") {
  292.         aSubject.getTransferData("moz/rdfitem", dataObj, len);
  293.         contentObject = this._coop.get(dataObj.value.QueryInterface(Components.interfaces.nsISupportsString).data);
  294.         message.subject = contentObject.name;
  295.         message.body = actionSubject.description;
  296.  
  297.         if (contentObject.isInstanceOf(this._coop.FeedItem)) {
  298.           aSubject.getTransferData("text/html", dataObj, len);
  299.           message.body = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString).data;
  300.         }
  301.         break;
  302.       }
  303.       if (child.data == "text/x-moz-url") {
  304.         aSubject.getTransferData("text/x-moz-url", dataObj, len);
  305.         contentObject = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString).data.split("\n");
  306.         message.subject = contentObject[1];
  307.         message.body = "I found this cool link with Flock:\n\n" + contentObject[0] + "\n";
  308.         break;
  309.       }
  310.       if (child.data == "text/unicode") {
  311.         aSubject.getTransferData("text/unicode", dataObj, len);
  312.         message.subject = "Saw this on a webpage, thought it was cool";
  313.         message.body = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString).data;
  314.         break;
  315.       }
  316.       flavourEnum.next();
  317.     }
  318.   } catch (ex) { //ignore this, just bad enumerator usage
  319.   }
  320.   if (!message) {
  321.     this._logger.info("I can't do anything without a supported flavour item, sorry.");
  322.     throw "No Supported Flavour for Sharing";
  323.   }
  324.   return message;
  325. }
  326.  
  327.  
  328. flockAccountUtils.prototype.getServiceIDForAccountURN =
  329. function flockAccountUtils_getServiceIDForAccountURN(aAccountURN)
  330. {
  331.   var account = this._coop.get(aAccountURN);
  332.   return account.serviceId;
  333. }
  334.  
  335. flockAccountUtils.prototype.createAccount =
  336. function flockAccountUtils_createAccount(aService, aUsername)
  337. {
  338.   aService.QueryInterface(Components.interfaces.nsIClassInfo);
  339.   
  340.   // Add the account
  341.   var accountURN = aService.urn+":"+aUsername;
  342.   var account = new this._coop.Account(accountURN, {
  343.     name: aUsername,
  344.     serviceId: aService.contractId,
  345.     service: null, // FIXME
  346.     accountId: aUsername,
  347.     favicon: aService.icon,
  348.     URL: aService.url,
  349.   });
  350.   this._coop.accounts_root.children.addOnce(account);
  351.   // this.USER = blAccount.id();
  352.   // var acct = this.getAccount(blAccount.id());
  353.  
  354.   // Add the notification stream
  355.   var notificationStream = new this._coop.Stream(accountURN + ":notifications", {
  356.     name: "Notification",
  357.     isPollable: false,
  358.     isIndexable: false,
  359.     notify: true,
  360.     serviceId: aService.contractId
  361.   });
  362.   account.children.addOnce(notificationStream);
  363.   return accountURN;
  364. }
  365.  
  366. flockAccountUtils.prototype.removeAccount =
  367. function flockAccountUtils_removeAccount(aAccountUrn)
  368. {
  369.   this._logger.info("{flockIAccountUtils}.removeAccount('"+aAccountUrn+"')");
  370.   var c_acct = this._coop.get(aAccountUrn);
  371.  
  372.   // Remove associated passwords
  373.   if (c_acct.accountId && c_acct.serviceId && Components.classes[c_acct.serviceId]) {
  374.     var svc = Components.classes[c_acct.serviceId]
  375.                         .getService(Components.interfaces.flockIWebService);
  376.     if (svc) {
  377.       // Clear the internal password entry that some services use
  378.       var internalPWhost = svc.urn+":"+c_acct.accountId;
  379.       this.clearTempPassword(internalPWhost);
  380.       this.removeAllPasswordsForHost(internalPWhost);
  381.       // Clear the user-created password entry for this account, if we can
  382.       // positively identify one
  383.       if (svc instanceof Components.interfaces.flockIManageableWebService) {
  384.         svc.QueryInterface(Components.interfaces.flockIManageableWebService);
  385.         var pm = Components.classes["@mozilla.org/passwordmanager;1"]
  386.                            .getService(Components.interfaces.nsIPasswordManager);
  387.         var en = pm.enumerator;
  388.         var domains = this._coop.get(svc.urn).domains.split(",");
  389.         while (en.hasMoreElements()) {
  390.           var p = en.getNext();
  391.           p.QueryInterface(Components.interfaces.nsIPassword);
  392.           for (var i = 0; i < domains.length; i++) {
  393.             var domain = domains[i];
  394.             var index = p.host.indexOf("."+domain);
  395.             if ( (p.host == "http://"+domain) || (p.host == "https://"+domain) ||
  396.                 ((index != -1) && (index + domain.length + 1 == p.host.length)) )
  397.             {
  398.               // The host for this password matches the service domain
  399.               try {
  400.                 if (p.user == c_acct.username || p.user == c_acct.accountId) {
  401.                   // And the username matches the account, so remove this entry
  402.                   pm.removeUser(p.host, p.user);
  403.                 }
  404.               } catch (ex) {
  405.                 this._logger.debug("ERROR removing password {host: "+p.host+" user: "+c_acct.username+"}");
  406.               }
  407.             }
  408.           }
  409.         }
  410.       }
  411.     }
  412.   }
  413.  
  414.   // Remove all of this Account's children which are Streams or Blogs
  415.   var acctChildren = c_acct.children.enumerate();
  416.   while (acctChildren.hasMoreElements()) {
  417.     var acctChild = acctChildren.getNext();
  418.     if (acctChild.isInstanceOf("http://flock.com/rdf#Stream")) {
  419.       this._logger.info("    removing account Stream");
  420.       var stream = acctChild;
  421.       // Remove all Stream items
  422.       var streamChildren = stream.children.enumerate();
  423.       while (streamChildren.hasMoreElements()) {
  424.         var streamChild = streamChildren.getNext();
  425.         var parents = streamChild.getParents();
  426.         for (var j = 0; j < parents.length; j++) {
  427.           parents[j].children.remove(streamChild);
  428.         }
  429.         streamChild.destroy();
  430.       }
  431.       // Remove Stream from all parents
  432.       var parents = stream.getParents();
  433.       for (var k = 0; k < parents.length; k++) {
  434.         parents[k].children.remove(stream);
  435.       }
  436.       stream.destroy();
  437.     }
  438.     else if (acctChild.isInstanceOf("http://flock.com/rdf#Blog")) {
  439.       this._logger.info("    removing account Blog");
  440.       var parents = acctChild.getParents();
  441.       for (var k = 0; k < parents.length; k++) {
  442.         parents[k].children.remove(acctChild);
  443.       }
  444.       acctChild.destroy();
  445.     }
  446.   }
  447.  
  448.   // Remove this Account from all of its parents
  449.   var parents = c_acct.getParents();
  450.   this._logger.info("  account "+aAccountUrn+" has "+parents.length+" parents");
  451.   for (var i = 0; i < parents.length; i++) {
  452.     this._logger.info("   removing from parent "+i);
  453.     parents[i].children.remove(c_acct);
  454.   }
  455.   this._logger.info("  destroying account "+aAccountUrn);
  456.   c_acct.destroy();
  457. }
  458.  
  459. flockAccountUtils.prototype.removeAllAccounts =
  460. function flockAccountUtils_removeAllAccounts()
  461. {
  462.   var c_accounts = this.getAllAccounts();
  463.   while (c_accounts.hasMoreElements()) {
  464.     var c_acct = c_accounts.getNext();
  465.     var svc = Components.classes[c_acct.serviceId]
  466.                         .getService(Components.interfaces.flockIWebService);
  467.     var acct = svc.getAccount(c_acct.id());
  468.     acct.logout(null);
  469.     svc.removeAccount(c_acct.id());
  470.   }
  471. }
  472.  
  473. flockAccountUtils.prototype.getCookie =
  474. function flockAccountUtils_getCookie(aHost, aCookieName)
  475. {
  476.   var ios = Components.classes["@mozilla.org/network/io-service;1"]
  477.                       .getService(Components.interfaces.nsIIOService);
  478.   var cookieSvc = Components.classes["@mozilla.org/cookieService;1"]
  479.                             .getService(Components.interfaces.nsICookieService);
  480.   var uri = ios.newURI(aHost, null, null);
  481.   var cookieString = cookieSvc.getCookieString(uri, null);
  482.   if (!cookieString) { return null; }
  483.   var index = cookieString.indexOf(aCookieName + "=");  
  484.   if (index == -1) { return null; }
  485.   index = cookieString.indexOf("=", index) + 1;  
  486.   var endstr = cookieString.indexOf(";", index);  
  487.   if (endstr == -1) {
  488.     endstr = cookieString.length;  
  489.   }
  490.   var cookieValue = unescape(cookieString.substring(index, endstr));
  491.   this._logger.info("{flockIAccountUtils}.getCookie('"+aHost+"', '"+aCookieName+"'): value = "+cookieValue);
  492.   return cookieValue;
  493. }
  494.  
  495. flockAccountUtils.prototype.getActiveBookmarkAccount =
  496. function flockAccountUtils_getActiveBookmarkAccount()
  497. {
  498.   this._logger.info("{flockIAccountUtils}.getActiveBookmarkAccountURU()");
  499.   var accounts = this._coop.Account.find({isTransient: false, isAuthenticated: true});
  500.   for (var i = 0; i < accounts.length; i++) {
  501.     try {
  502.       var svn = Components.classes[accounts[i].serviceId]
  503.                           .getService(Components.interfaces.flockIBookmarkWebService);
  504.     } catch (ex) {
  505.       continue;
  506.     }
  507.     svn.QueryInterface(Components.interfaces.flockIWebService);
  508.     var account = svn.getAccount(accounts[i].id());
  509.     account.QueryInterface(Components.interfaces.flockIBookmarkWebServiceAccount);
  510.     return account;
  511.   }
  512.   return null;
  513. }
  514.  
  515. flockAccountUtils.prototype.getFirstAuthenticatedAccountForService =
  516. function flockAccountUtils_getFirstAuthenticatedAccountForService(aServiceContractID)
  517. {
  518.   this._logger.info("{flockIAccountUtils}.getFirstAuthenticatedAccountForService('"+aServiceContractID+"')");
  519.   this.setup();
  520.   var accounts = this._coop.Account.find({serviceId: aServiceContractID, isAuthenticated: true});
  521.   if (accounts.length) {
  522.     return accounts[0].id();
  523.   }
  524.   return null;
  525. }
  526.  
  527. flockAccountUtils.prototype.getPassword =
  528. function flockAccountUtils_getPassword(aKey)
  529. {
  530.   this._logger.info("{flockIAccountUtils}.getPassword('"+aKey+"')");
  531.   var pw = this.getTempPassword(aKey);
  532.   if (!pw) {
  533.     pw = this.getFirstPasswordForHost(aKey);
  534.   }
  535.   return pw;
  536. }
  537.  
  538. flockAccountUtils.prototype.getPasswordForAnyHost =
  539. function flockAccountUtils_getPasswordForAnyHost(aDomain)
  540. {
  541.   this._logger.info("{flockIAccountUtils}.getPasswordForAnyHost('"+aDomain+"')");
  542.   var pm = Components.classes["@mozilla.org/passwordmanager;1"]
  543.                      .getService(Components.interfaces.nsIPasswordManager);
  544.   var en = pm.enumerator;
  545.   while (en.hasMoreElements()) {
  546.     var p = en.getNext();
  547.     p.QueryInterface(Components.interfaces.nsIPassword);
  548.     this._logger.info(" comparing to host: "+p.host);
  549.     if ((p.host == aDomain)
  550.         || (p.host == "http://"+aDomain)
  551.         || (p.host == "https://"+aDomain))
  552.     {
  553.       // found a password for this exact domain
  554.       return p;
  555.     }
  556.     var index = p.host.indexOf("."+aDomain);
  557.     if ((index != -1) && (index + aDomain.length + 1 == p.host.length)) {
  558.       // matched a host in the specified domain
  559.       return p;
  560.     }
  561.   }
  562.   return null;
  563. }
  564.  
  565. flockAccountUtils.prototype.getFirstPasswordForHost =
  566. function flockAccountUtils_getFirstPasswordForHost(aHost)
  567. {
  568.   this._logger.info("{flockIAccountUtils}.getFirstPasswordForHost('"+aHost+"')");
  569.   var pm = Components.classes["@mozilla.org/passwordmanager;1"]
  570.                      .getService(Components.interfaces.nsIPasswordManager);
  571.   var en = pm.enumerator;
  572.   while (en.hasMoreElements()) {
  573.     var p = en.getNext();
  574.     p.QueryInterface(Components.interfaces.nsIPassword);
  575.     if (p.host == aHost) {
  576.       return p;
  577.     }
  578.   }
  579.   return null;
  580. }
  581.  
  582. flockAccountUtils.prototype.getTempPassword =
  583. function flockAccountUtils_getTempPassword(aKey)
  584. {
  585.   this._logger.info("{flockIAccountUtils}.getTempPassword('"+aKey+"')");
  586.   return this.mTempPasswords[aKey];
  587. }
  588.  
  589. flockAccountUtils.prototype.makeTempPasswordPermanent =
  590. function flockAccountUtile_makeTempPasswordPermanent(aKey)
  591. {
  592.   this._logger.info("{flockIAccountUtils}.makeTempPasswordPermanent('"+aKey+"')");
  593.   var temp = this.getTempPassword(aKey);
  594.   if (temp) {
  595.     this.removeAllPasswordsForHost(aKey);
  596.     this.setPassword(aKey, temp.user, temp.password);
  597.     this.clearTempPassword(aKey);
  598.     return this.getPassword(aKey);
  599.   } else {
  600.     this._logger.info(" - ERROR: temporary password does not exist!  Can't make it permanent...");
  601.     // TODO: Maybe throw an exception here?
  602.   }
  603.   return null;
  604. }
  605.  
  606. flockAccountUtils.prototype.markAllAccountsAsLoggedOut =
  607. function flockAccountUtils_markAllAccountsAsLoggedOut(aServiceContractID)
  608. {
  609.   this._logger.info("{flockIAccountUtils}.markAllAccountsAsLoggedOut('"+aServiceContractID+"')");
  610.   this.setup();
  611.   var accounts = this._coop.Account.find({serviceId: aServiceContractID});
  612.   for (var i = 0; i < accounts.length; i++) {
  613.     accounts[i].isAuthenticated = false;
  614.   }
  615. }
  616.  
  617. flockAccountUtils.prototype.setPassword =
  618. function flockAccountUtils_setPassword(aHost, aUser, aPassword)
  619. {
  620.   this._logger.info("{flockIAccountUtils}.setPassword('"+aHost+"', '"+aUser+"', 'XXXXXX')");
  621.   var pm = Components.classes["@mozilla.org/passwordmanager;1"]
  622.                      .getService(Components.interfaces.nsIPasswordManager);
  623.   try {
  624.     pm.addUser(aHost, aUser, aPassword);
  625.   } catch (ex) {
  626.     this._logger.warn("addUser('"+aHost+"', '"+aUser+"') FAILED: "+ex);
  627.   }
  628. }
  629.  
  630. flockAccountUtils.prototype.setTempPassword =
  631. function flockAccountUtils_setTempPassword(aKey, aUser, aPassword, aFormType)
  632. {
  633.   this._logger.info("{flockIAccountUtils}.setTempPassword('"+aKey+"', '"+aUser+"', 'XXXXXXXX', '"+aFormType+"')");
  634.   var pw = {
  635.     QueryInterface: function(aIID) {
  636.       if (!aIID.equals(Components.interfaces.nsISupports) &&
  637.           !aIID.equals(Components.interfaces.nsIPassword) &&
  638.           !aIID.equals(Components.interfaces.flockIPasswordOrigin)) {
  639.         throw Components.interfaces.NS_ERROR_NO_INTERFACE;
  640.       }
  641.       return this;
  642.     },
  643.     host: aKey,
  644.     user: aUser,
  645.     password: aPassword,
  646.     formType: aFormType
  647.   };
  648.   this.mTempPasswords[aKey] = pw;
  649. }
  650.  
  651. flockAccountUtils.prototype.removeAllPasswordsForHost =
  652. function flockAccountUtils_removeAllPasswordsForHost(aHost)
  653. {
  654.   this._logger.info("{flockIAccountUtils}.removeAllPasswordsForHost('"+aHost+"')");
  655.   var pm = Components.classes["@mozilla.org/passwordmanager;1"]
  656.                      .getService(Components.interfaces.nsIPasswordManager);
  657.   var en = pm.enumerator;
  658.   while (en.hasMoreElements()) {
  659.     var p = en.getNext()
  660.               .QueryInterface(Components.interfaces.nsIPassword);
  661.     if (p.host == aHost) {
  662.       try {
  663.         pm.removeUser(p.host, p.user);
  664.       } catch (ex) {
  665.         this._logger.debug( "ERROR - perhaps an attempt to remove a password "
  666.                           + "that has already been removed... ?");
  667.         this._logger.debug(" host: "+aHost);
  668.       }
  669.     }
  670.   }
  671. }
  672.  
  673. flockAccountUtils.prototype.raiseNotification =
  674. function flockAccountUtils_raiseNotification(aStreamUrn, aNotificationUrn, aNotificationProps)
  675. {
  676.   this._logger.info("{flockIAccountUtils}.raiseNotification('"+aStreamUrn+"', '"+aNotificationUrn+"', aNotificationProps)");
  677.   aNotificationProps.QueryInterface(Components.interfaces.nsIPropertyBag);
  678.   var notification = new this._coop.Notification(aNotificationUrn);
  679.   notification.datevalue = new Date();
  680.   var props = aNotificationProps.enumerator;
  681.   while (props.hasMoreElements()) {
  682.     var prop = props.getNext();
  683.     prop.QueryInterface(Components.interfaces.nsIProperty);
  684.     notification[prop.name] = prop.value;
  685.   }
  686.   var notificationStream = this._coop.get(aStreamUrn);
  687.   notificationStream.children.addOnce(notification);
  688.   // OBS.notifyObservers(this, "new-stuff-notification", notification.id());
  689. }
  690.  
  691. flockAccountUtils.prototype.extractPasswordFromHTMLForm =
  692. function flockAccountUtils_extractPasswordFromHTMLForm(aForm)
  693. {
  694.   this._logger.info("{flockIAccountUtils}.extractPasswordFromHTMLForm(aForm)");
  695.   aForm.QueryInterface(Components.interfaces.nsIDOMHTMLFormElement);
  696.   var formElements = aForm.elements;
  697.   var passElements = [];
  698.   var username = "";
  699.   var firstPasswordIndex = formElements.length;
  700.   for (var i = 0; i < formElements.length; i++) {
  701.     var formElement = formElements.item(i);
  702.     if (formElement.type == "password") {
  703.       passElements.push(formElement);
  704.       if (firstPasswordIndex == formElements.length) {
  705.         firstPasswordIndex = i;
  706.       }
  707.     }
  708.   }
  709.   if (firstPasswordIndex == formElements.length) {
  710.     // We didn't find a password
  711.     return null;
  712.   }
  713.   // Backwards to get closest text field
  714.   for (var i = firstPasswordIndex - 1; i >= 0; i--) {
  715.     var formElement = formElements.item(i);
  716.     if (formElement.type == "text") {
  717.       username = formElement.value;
  718.       break;
  719.     }
  720.   }
  721.   var pwObj = {
  722.     host: "",
  723.     password: passElements[0].value,
  724.     user: username
  725.   };
  726.   return pwObj;
  727. }
  728.  
  729. flockAccountUtils.prototype.decorateDocument =
  730. function flockAccountUtils_decorateDocument(aDocument, aCategory, aName, aValue)
  731. {
  732.   this._logger.info("{flockIAccountUtils}.decorateDocument(aDocument, '"+aCategory+"', '"+aName+"', '"+aValue+"')");
  733.   aDocument.QueryInterface(Components.interfaces.nsIDOMHTMLDocument);
  734.   if (!aDocument._flock_decorations) {
  735.     aDocument._flock_decorations = {};
  736.   }
  737.   var fd = aDocument._flock_decorations;
  738.   if (!fd[aCategory]) {
  739.     fd[aCategory] = {};
  740.   }
  741.   fd[aCategory][aName] = aValue;
  742. }
  743.  
  744. flockAccountUtils.prototype.getDocumentDecoration =
  745. function flockAccountUtils_getDocumentDecoration(aDocument, aCategory, aName)
  746. {
  747.   this._logger.info("{flockIAccountUtils}.getDocumentDecoration(aDocument, '"+aCategory+"', '"+aName+"')");
  748.   aDocument.QueryInterface(Components.interfaces.nsIDOMHTMLDocument);
  749.   try {
  750.     var value = aDocument._flock_decorations[aCategory][aName];
  751.     return value;
  752.   } catch (ex) {
  753.     return null;
  754.   }
  755. }
  756.  
  757. flockAccountUtils.prototype.useWebDetective =
  758. function flockAccountUtils_useWebDetective(aDetectionFileName)
  759. {
  760.   this._logger.info("{flockIAccountUtils}.useWebDetective('"+aDetectionFileName+"')");
  761.   this.setup();
  762.   var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
  763.                          .getService(Components.interfaces.nsIProperties);
  764.   var profDir = dirSvc.get("ProfD", Components.interfaces.nsIFile);
  765.   var file = Components.classes["@mozilla.org/file/local;1"]
  766.                        .createInstance(Components.interfaces.nsILocalFile);
  767.   file.initWithPath(profDir.path);
  768.   file.append("detect");
  769.   var profDetectDir = file.clone();
  770.   if (!profDetectDir.exists()) {
  771.     profDetectDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
  772.   }
  773.   file.append(aDetectionFileName);
  774.   if (!file.exists()) {
  775.     // The file doesn't exist in the profile, so check if there's one in the
  776.     // res folder that we can copy over
  777.     var resDir = dirSvc.get("ARes", Components.interfaces.nsIFile);
  778.     var file2 = Components.classes["@mozilla.org/file/local;1"]
  779.                           .createInstance(Components.interfaces.nsILocalFile);
  780.     file2.initWithPath(resDir.path);
  781.     file2.append("detect");
  782.     file2.append(aDetectionFileName);
  783.     if (!file2.exists()) {
  784.       this._logger.info("File does not exist: "+aDetectionFileName);
  785.     }
  786.     file2.copyTo(profDetectDir, aDetectionFileName);
  787.     file = profDetectDir.clone();
  788.     file.append(aDetectionFileName);
  789.   }
  790.   var webDetective = Components.classes["@flock.com/web-detective;1"]
  791.                                .getService(Components.interfaces.flockIWebDetective);
  792.   webDetective.loadDetectFile(file);
  793.   return webDetective;
  794. }
  795.  
  796. flockAccountUtils.prototype.removeCookies =
  797. function flockAccountUtils_removeCookies(aCookies)
  798. {
  799.   aCookies.QueryInterface(Components.interfaces.nsISimpleEnumerator);
  800.   var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
  801.                                 .getService(Components.interfaces.nsICookieManager);
  802.   var deletedCount = 0;
  803.   while (aCookies.hasMoreElements()) {
  804.     var c = aCookies.getNext()
  805.       .QueryInterface(Components.interfaces.nsICookie);
  806.     cookieManager.remove(c.host, c.name, c.path, false);
  807.     deletedCount++;
  808.   }
  809.   this._logger.info(".removeCookies() - Deleted "+deletedCount+" cookies");
  810. }
  811. // END flockIAccountUtils interface
  812.  
  813.  
  814. // BEGIN helper functions
  815. flockAccountUtils.prototype.setup =
  816. function flockAccountUtils_setup()
  817. {
  818.   if (this.mSetupHasRun) {
  819.     return;
  820.   } else {
  821.     this.mSetupHasRun = true;
  822.     this._coop = Components.classes["@flock.com/singleton;1"]
  823.       .getService(Components.interfaces.flockISingleton)
  824.       .getSingleton("chrome://browser/content/flock/common/load-faves-coop.js")
  825.       .wrappedJSObject;
  826.   }
  827. }
  828.  
  829. flockAccountUtils.prototype.getAllAccounts =
  830. function flockAccountUtils_getAllAccounts()
  831. {
  832.   return this._coop.Account.all();
  833. }
  834. // END helper functions
  835.  
  836. // ========== END flockAccountUtils class ==========
  837.  
  838.  
  839.  
  840. // ================================================
  841. // ========== BEGIN XPCOM Module support ==========
  842. // ================================================
  843.  
  844. // BEGIN flockAccountUtilsModule object
  845. var flockAccountUtilsModule = {};
  846.  
  847. flockAccountUtilsModule.registerSelf =
  848. function flockAccountUtilsModule_registerSelf(compMgr, fileSpec, location, type)
  849. {
  850.   compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  851.   compMgr.registerFactoryLocation( ACCOUNTUTILS_CID, 
  852.                                    "Flock Account Utils JS Component",
  853.                                    ACCOUNTUTILS_CONTRACTID, 
  854.                                    fileSpec, 
  855.                                    location,
  856.                                    type );
  857. }
  858.  
  859. flockAccountUtilsModule.getClassObject =
  860. function flockAccountUtilsModule_getClassObject(compMgr, cid, iid)
  861. {
  862.   if (!cid.equals(ACCOUNTUTILS_CID)) {
  863.     throw Components.results.NS_ERROR_NO_INTERFACE;
  864.   }
  865.   if (!iid.equals(Components.interfaces.nsIFactory)) {
  866.     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  867.   }
  868.   return flockAccountUtilsFactory;
  869. }
  870.  
  871. flockAccountUtilsModule.canUnload =
  872. function flockAccountUtilsModule_canUnload(compMgr)
  873. {
  874.   return true;
  875. }
  876. // END flockAccountUtilsModule object
  877.  
  878.  
  879. // BEGIN flockAccountUtilsFactory object
  880. var flockAccountUtilsFactory = {};
  881.  
  882. flockAccountUtilsFactory.createInstance =
  883. function flockAccountUtilsFactory_createInstance(outer, iid)
  884. {
  885.   if (outer != null) {
  886.     throw Components.results.NS_ERROR_NO_AGGREGATION;
  887.   }
  888.   return (new flockAccountUtils()).QueryInterface(iid);
  889. }
  890. // END flockAccountUtilsFactory object
  891.  
  892.  
  893. // NS module entry point
  894. function NSGetModule(compMgr, fileSpec) {
  895.   return flockAccountUtilsModule;
  896. }
  897.  
  898. // ========== END XPCOM module support ==========
  899.